package config

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
)

// Config 应用程序配置
type Config struct {
	Server  ServerConfig  `json:"server"`
	Storage StorageConfig `json:"storage"`
	Web     WebConfig     `json:"web"`
}

// ServerConfig 服务器配置
type ServerConfig struct {
	IP   string `json:"ip"`   // 监听IP地址
	Port string `json:"port"`
}

// StorageConfig 存储配置
type StorageConfig struct {
	Path        string `json:"path"`        // 分享的文件夹路径
	MaxFileSize int64  `json:"maxFileSize"`
	MaxMemory   int64  `json:"maxMemory"`
}

// WebConfig 前端配置
type WebConfig struct {
	DistPath string `json:"distPath,omitempty"` // 可选：外部前端文件路径，留空则使用内嵌文件
}

// DefaultConfig 默认配置
var DefaultConfig = Config{
	Server: ServerConfig{
		IP:   "0.0.0.0",
		Port: "3001",
	},
	Storage: StorageConfig{
		Path:        "../shared-files",
		MaxFileSize: 100 * 1024 * 1024, // 100MB
		MaxMemory:   32 << 20,           // 32MB
	},
	Web: WebConfig{
		DistPath: "", // 空字符串表示使用内嵌文件系统
	},
}

// GetExecutableDir 获取可执行文件所在目录
func GetExecutableDir() (string, error) {
	exe, err := os.Executable()
	if err != nil {
		return "", err
	}
	return filepath.Dir(exe), nil
}

// LoadConfigFromFile 从JSON文件加载配置
func LoadConfigFromFile(configPath string) (*Config, error) {
	data, err := os.ReadFile(configPath)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %v", err)
	}

	var config Config
	if err := json.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %v", err)
	}

	return &config, nil
}

// SaveConfigToFile 保存配置到JSON文件
func SaveConfigToFile(config *Config, configPath string) error {
	data, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		return fmt.Errorf("序列化配置失败: %v", err)
	}

	if err := os.WriteFile(configPath, data, 0644); err != nil {
		return fmt.Errorf("写入配置文件失败: %v", err)
	}

	return nil
}

// GetConfig 获取配置
func GetConfig() (*Config, error) {
	// 首先尝试从可执行文件同目录读取配置文件
	configPath, err := getConfigPath()
	if err != nil {
		return nil, fmt.Errorf("获取配置文件路径失败: %v", err)
	}

	// 如果配置文件不存在，创建默认配置
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		fmt.Printf("配置文件不存在，创建默认配置: %s\n", configPath)
		config := getDefaultConfig()
		if err := saveConfig(config, configPath); err != nil {
			return nil, fmt.Errorf("保存默认配置失败: %v", err)
		}
		return config, nil
	}

	// 读取配置文件
	data, err := os.ReadFile(configPath)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %v", err)
	}

	var config Config
	if err := json.Unmarshal(data, &config); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %v", err)
	}

	// 应用环境变量覆盖
	applyEnvOverrides(&config)

	// 验证配置
	if err := validateConfig(&config); err != nil {
		return nil, fmt.Errorf("配置验证失败: %v", err)
	}

	return &config, nil
}

// getConfigPath 获取配置文件路径（可执行文件同目录）
func getConfigPath() (string, error) {
	// 获取可执行文件路径
	execPath, err := os.Executable()
	if err != nil {
		return "", err
	}

	// 获取可执行文件所在目录
	execDir := filepath.Dir(execPath)
	
	// 配置文件在同目录下
	configPath := filepath.Join(execDir, "config.json")
	
	return configPath, nil
}

// getDefaultConfig 获取默认配置
func getDefaultConfig() *Config {
	return &Config{
		Server: ServerConfig{
			IP:   "0.0.0.0",
			Port: "3001",
		},
		Storage: StorageConfig{
			Path:        "./shared-files",
			MaxFileSize: 100 * 1024 * 1024, // 100MB
			MaxMemory:   32 << 20,           // 32MB
		},
		Web: WebConfig{
			DistPath: "", // 空字符串表示使用内嵌文件系统
		},
	}
}

// applyEnvOverrides 应用环境变量覆盖
func applyEnvOverrides(config *Config) {
	if port := os.Getenv("PORT"); port != "" {
		config.Server.Port = port
	}
	
	if storagePath := os.Getenv("STORAGE_PATH"); storagePath != "" {
		config.Storage.Path = storagePath
	}
	
	if distPath := os.Getenv("DIST_PATH"); distPath != "" {
		config.Web.DistPath = distPath
	}
	
	if host := os.Getenv("HOST"); host != "" {
		config.Server.IP = host
	}
}

// validateConfig 验证配置
func validateConfig(config *Config) error {
	if config.Server.IP == "" {
		return fmt.Errorf("监听IP地址不能为空")
	}
	
	if config.Server.Port == "" {
		return fmt.Errorf("端口不能为空")
	}
	
	if config.Storage.Path == "" {
		return fmt.Errorf("存储路径不能为空")
	}
	
	return nil
}

// saveConfig 保存配置到文件
func saveConfig(config *Config, path string) error {
	data, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		return err
	}
	
	return os.WriteFile(path, data, 0644)
} 